package com.androidme.app.framework.widget.advert;


import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.*;
import android.view.animation.Animation.AnimationListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.androidme.R;
import com.androidme.app.framework.base.AndroidMeApplication;
import com.androidme.app.framework.util.MD5Util;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


public class AdvertView extends RelativeLayout {

    Context context;

    protected static LayoutInflater mLayoutInflater;

    AdvertView mAdvertView;

    AdvertViewFlipper mViewFlipper;

    LinearLayout mFootView;

    private Animation mAnimationIn;

    private Animation mAnimationOut;

    private AnimationSet mAnimationInSet;

    private AnimationSet mAnimationOutSet;

    private static final int RIGHT_TO_LEFT = 1;

    private static final int LEFT_TO_RIGHT = RIGHT_TO_LEFT + 1;

    private static final int DOWN_TO_UP = LEFT_TO_RIGHT + 1;

    private static final int DOWN_TO_UP_CON = DOWN_TO_UP + 1;

    private static final int UP_TO_DOWN = DOWN_TO_UP_CON + 1;

    private static final int UP_TO_DOWN_CON = UP_TO_DOWN + 1;

    private static final int FADE_ANI = UP_TO_DOWN_CON + 1;

    public ArrayList<AdvertModel> advList = new ArrayList<AdvertModel>();

    private HashMap<String, Bitmap> advertMap = new HashMap<String, Bitmap>();

    private Activity mActivity;

    private boolean isMove = false;

    public static HashMap<String, Integer> HMmotion = new HashMap<String, Integer>();

    static {
        HMmotion.put("left", RIGHT_TO_LEFT);
        HMmotion.put("right", LEFT_TO_RIGHT);
        HMmotion.put("up", DOWN_TO_UP_CON);
        HMmotion.put("down", UP_TO_DOWN_CON);
        HMmotion.put("fade", FADE_ANI);
    }

    public AdvertView(Context context) {
        super(context);
        this.context = context;
    }

    public AdvertView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public AdvertView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
    }

    public void setActivity(Activity mActivity) {
        this.mActivity = mActivity;
        init();
    }

    private void init() {
        mAdvertView = (AdvertView) mActivity.findViewById(R.id.advert_view);
        mViewFlipper = (AdvertViewFlipper) mActivity
                .findViewById(R.id.advert_flipper);
        mFootView = (LinearLayout) mActivity
                .findViewById(R.id.advert_view_foot);
        SetCustomAnimation(RIGHT_TO_LEFT, 1000);
        advList.clear();
        mViewFlipper.setAnimateFirstView(false);
    }

    public void initAdvertList(ArrayList<AdvertModel> list) {
        if (advList.size() != list.size()) {
            advList.clear();
            mViewFlipper.removeAllViews();
            mFootView.removeAllViews();
            advList = list;
        }
        onRefresh();
        if (this.getVisibility() != View.VISIBLE && mViewFlipper.getChildCount() > 0) {
            setAdvertVisibility(View.VISIBLE);

        }
        if (mViewFlipper.getChildCount() > 1) {
            startFlipper();
        }
        onRefreshFoot();
    }

    public void addAdvert(AdvertModel adv) {
        File file = new File(AndroidMeApplication.FILE_PIC_ADVERT,
                getImageName(adv.getPic()));
        if (file.exists() == true) {
            ImageButton mBtnAdvert = new ImageButton(context);
            mBtnAdvert.setPadding(0, 0, 0, 0);
            mBtnAdvert.setScaleType(ImageButton.ScaleType.FIT_XY);
            mBtnAdvert.setTag(adv);
            mBtnAdvert.setOnClickListener(mOnClickListener);
            mBtnAdvert.setOnTouchListener(mOnTouchListener);
            Map<String, Bitmap> map = Collections.synchronizedMap(advertMap);
            String key = file.getAbsolutePath();
            if (map.containsKey(key)) {
                mBtnAdvert.setImageBitmap(map.get(key));
                mViewFlipper.addView(mBtnAdvert);
            } else {
                try {
                    Bitmap bitmap = BitmapFactory.decodeFile(key);
                    map.put(key, bitmap);
                    mBtnAdvert.setImageBitmap(bitmap);
                    mViewFlipper.addView(mBtnAdvert);
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void addIndicator(int i) {
        if (mFootView != null && mFootView.getVisibility() == View.VISIBLE) {
            ImageButton mBtnIndicator = new ImageButton(context);
            Drawable drawable = context.getResources().getDrawable(
                    R.drawable.advert_indicator);
            mBtnIndicator.setImageDrawable(drawable);
            mBtnIndicator.setBackgroundColor(0x00000000);
            mBtnIndicator.setPadding(0, 0, 0, 0);
            mBtnIndicator.setTag(i);
            final int tempi = i;
            mBtnIndicator.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mViewFlipper.setDisplayedChild(tempi);
                }
            });
            mFootView.addView(mBtnIndicator, drawable.getIntrinsicWidth() + 5,
                    LayoutParams.FILL_PARENT);
        }
    }

    public void onRefresh() {
        if (mViewFlipper.getChildCount() != advList.size()) {
            mViewFlipper.removeAllViews();
            mFootView.removeAllViews();
            for (int i = 0; i < advList.size(); i++) {
                AdvertModel adv = advList.get(i);
                File file = new File(AndroidMeApplication.FILE_PIC_ADVERT, getImageName(adv.getPic()));
                if (file.exists() == true) {
                    addAdvert(adv);
                    addIndicator(i);
                }
            }
        } else {

        }

    }

    public void onRefreshFoot() {
        if (mViewFlipper != null && mFootView != null
                && mFootView.getVisibility() == View.VISIBLE) {
            int index = mViewFlipper.getDisplayedChild();
            int count = mFootView.getChildCount();
            for (int i = 0; i < count; i++) {
                ImageButton mBtnIndicator = (ImageButton) mFootView
                        .getChildAt(i);
                if (mBtnIndicator instanceof ImageButton) {
                    int tag = (Integer) mFootView.getChildAt(i).getTag();
                    if (tag == index) {
                        mBtnIndicator
                                .setImageResource(R.drawable.advert_indicator_selected);
                    } else {
                        mBtnIndicator.setImageResource(R.drawable.advert_indicator);
                    }
                }
            }
        }
    }

    public void startFlipper() {
        if (mViewFlipper != null) {
            mViewFlipper.startFlipping();
        }
    }

    public void stopFlipper() {
        if (mViewFlipper != null) {
            mViewFlipper.stopFlipping();
        }
    }

    public void setInAnimation(Animation inAnimation) {
        if (mViewFlipper != null) {
            mViewFlipper.setInAnimation(inAnimation);
        }
    }

    public void setOutAnimation(Animation outAnimation) {
        if (mViewFlipper != null) {
            mViewFlipper.setOutAnimation(outAnimation);
        }
    }

    public void setFootVisibility(int mVisibility) {
        if (mFootView != null) {
            mFootView.setVisibility(mVisibility);
        }
    }

    public void setAdvertVisibility(int mVisibility) {
        if (mAdvertView != null) {
            if (mVisibility != mAdvertView.getVisibility())
                mAdvertView.setVisibility(mVisibility);
        }
    }

    public void clear() {
        if (advertMap != null) {
            for (Bitmap bitmap : advertMap.values()) {
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();
                    bitmap = null;
                }
            }
            advertMap.clear();
            advertMap = null;
        }
    }

    private static String getImageName(String imgUri) {
        return MD5Util.md5(imgUri);
    }

    public void setAdvertInfo(AdvertInfo adInfo) {
        int animatetime = Integer.parseInt(adInfo.getAnimatetime());
        int staytime = Integer.parseInt(adInfo.getStaytime());
        String motion = adInfo.getMotion();
        int anitype = HMmotion.get(motion);
        SetCustomAnimation(anitype, animatetime);
        setFlipInterval(staytime);
    }

    public void setFlipInterval(int m) {
        mViewFlipper.setFlipInterval(m);
    }

    public void SetCustomAnimation(int anitype, int anidelaytime) {
        switch (anitype) {
            case RIGHT_TO_LEFT:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationRightIn = mAnimationInSet;
                animationRightIn.setInterpolator(new AccelerateInterpolator());
                animationRightIn.addAnimation(new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, 1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationRightIn.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationRightOut = mAnimationOutSet;
                animationRightOut.setInterpolator(new AccelerateInterpolator());
                animationRightOut.addAnimation(new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, -1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationRightOut.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);
                break;
            case LEFT_TO_RIGHT:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationLeftIn = mAnimationInSet;
                animationLeftIn.setInterpolator(new AccelerateInterpolator());
                animationLeftIn.addAnimation(new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, -1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationLeftIn.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationLeftOut = mAnimationOutSet;
                animationLeftOut.setInterpolator(new AccelerateInterpolator());
                animationLeftOut.addAnimation(new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationLeftOut.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);
                break;
            case DOWN_TO_UP:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationSetIn = mAnimationInSet;
                animationSetIn.setInterpolator(new AccelerateInterpolator());
                animationSetIn.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetIn.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationSetOut = mAnimationOutSet;
                animationSetOut.setInterpolator(new AccelerateInterpolator());
                animationSetOut.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetOut.setDuration(anidelaytime);
                animationSetOut.setStartTime(500);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);

                break;
            case DOWN_TO_UP_CON:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationSetInCon = mAnimationInSet;
                animationSetInCon.setInterpolator(new AccelerateInterpolator());
                animationSetInCon.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetInCon.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationSetOutCon = mAnimationOutSet;
                animationSetOutCon.setInterpolator(new AccelerateInterpolator());
                animationSetOutCon.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, -1.0f));
                animationSetOutCon.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);

                break;
            case UP_TO_DOWN:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationSetDownIn = mAnimationInSet;
                animationSetDownIn.setInterpolator(new AccelerateInterpolator());
                animationSetDownIn.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, -1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetDownIn.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationSetDownOut = mAnimationOutSet;
                animationSetDownOut.setInterpolator(new AccelerateInterpolator());
                animationSetDownOut.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetDownOut.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);

                break;
            case UP_TO_DOWN_CON:
                mAnimationInSet = new CustomAnimationSet();
                final AnimationSet animationSetDownInCon = mAnimationInSet;
                animationSetDownInCon.setInterpolator(new AccelerateInterpolator());
                animationSetDownInCon.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, -1.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f));
                animationSetDownInCon.setDuration(anidelaytime);
                mAnimationOutSet = new CustomAnimationSet();
                final AnimationSet animationSetDownOutCon = mAnimationOutSet;
                animationSetDownOutCon
                        .setInterpolator(new AccelerateInterpolator());
                animationSetDownOutCon.addAnimation(new TranslateAnimation(
                        Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                        Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF, 1.0f));
                animationSetDownOutCon.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationInSet);
                mViewFlipper.setOutAnimation(mAnimationOutSet);

                break;
            case FADE_ANI:
                mAnimationIn = AnimationUtils.loadAnimation(getContext(),
                        android.R.anim.fade_in);
                mAnimationOut = AnimationUtils.loadAnimation(getContext(),
                        android.R.anim.fade_out);

                mAnimationIn.setDuration(anidelaytime);
                mAnimationOut.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationIn);
                mViewFlipper.setOutAnimation(mAnimationOut);
                break;
            default:
                mAnimationIn = AnimationUtils.loadAnimation(getContext(),
                        android.R.anim.fade_in);
                mAnimationOut = AnimationUtils.loadAnimation(getContext(),
                        android.R.anim.fade_out);

                mAnimationIn.setDuration(anidelaytime);
                mAnimationOut.setDuration(anidelaytime);

                mViewFlipper.setInAnimation(mAnimationIn);
                mViewFlipper.setOutAnimation(mAnimationOut);
                break;
        }
        if (mAnimationOutSet != null)
            mAnimationOutSet.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    onRefreshFoot();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        if (mAnimationOut != null)
            mAnimationOut.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    onRefreshFoot();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
    }

    private float startX = 0.0f;
    private float startY = 0.0f;
    private float endX = 0.0f;
    private float endY = 0.0f;
    private float minSpace = 10.0f;
    private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = event.getRawX();
                    startY = event.getRawY();
                    isMove = false;
                    break;
                case MotionEvent.ACTION_MOVE:
                    endX = event.getRawX();
                    endY = event.getRawY();
                    // LogDebugger.debug("onTouch ACTION_MOVE",
                    // "x "+Math.abs(endX-startX)+" y "+Math.abs(endY-startY));
                    if (Math.abs(endX - startX) > minSpace
                            || Math.abs(endY - startY) > minSpace)
                        isMove = true;
                    break;
            }
            return false;
        }
    };

    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isMove == false && v instanceof ImageButton) {

                AdvertModel adv = (AdvertModel) v.getTag();
                //todo
            }
        }
    };

    private static class CustomAnimationSet extends AnimationSet {

        public CustomAnimationSet() {
            super(false);
        }

        @Override
        public boolean willChangeTransformationMatrix() {
            return true;
        }

        @Override
        public boolean willChangeBounds() {
            return false;
        }

    }
}
